#include "DHT11.h"

// 使用时需要将以下变量在main.c里声明为全局变量
uint8_t Humi_H, Humi_L, Temp_H, Temp_L;
uint8_t Temperature_integerPart = 0;
uint8_t Humidity_integerPart = 0;
uint8_t Presence = 0;
uint16_t flag=0;

void delay(uint16_t us)
{ // 微秒延时
  uint16_t differ = 0xffff - us - 5;
  __HAL_TIM_SET_COUNTER(&htim2, differ); // 设定TIM2计数器起始值
  HAL_TIM_Base_Start(&htim2);            // 启动定时器

  while (differ < 0xffff - 5)
  {                                         // 判断
    differ = __HAL_TIM_GET_COUNTER(&htim2); // 查询计数器的计数值
  }
  HAL_TIM_Base_Stop(&htim2);
} // 较为精确

void Set_Pin_Output(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  GPIO_InitStruct.Pin = GPIO_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOx, &GPIO_InitStruct);
}

void Set_Pin_Input(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  GPIO_InitStruct.Pin = GPIO_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(GPIOx, &GPIO_InitStruct);
}

void DHT11_Start(void)
{
  Set_Pin_Output(DHT11_GPIO_Port, DHT11_Pin);                    // 输出模式
  HAL_GPIO_WritePin(DHT11_GPIO_Port, DHT11_Pin, GPIO_PIN_RESET); // 拉低
  delay(18000);                                             // 18ms是通信协议的规定
  HAL_GPIO_WritePin(DHT11_GPIO_Port, DHT11_Pin, GPIO_PIN_SET);   // 拉高
  delay(20);                                                // 确保数据的发送
  Set_Pin_Input(DHT11_GPIO_Port, DHT11_Pin);                     // 输入模式
}

uint8_t DHT11_Check_Response(void)
{
  // uint8_t Response = 0;
  int8_t Response = 0;

  delay(40);
  if (HAL_GPIO_ReadPin(DHT11_GPIO_Port, DHT11_Pin) == GPIO_PIN_RESET)
  {
    delay(80);
    if ((HAL_GPIO_ReadPin(DHT11_GPIO_Port, DHT11_Pin)))
      Response = 1;
    else
      Response = -1; // 255
  }

  while ((HAL_GPIO_ReadPin(DHT11_GPIO_Port, DHT11_Pin))) // 等待引脚变为低电平（等待数据传输完成）
	{
		if(++flag>1000)
			break;
	}
	flag=0;
  return Response;
}

uint8_t DHT11_Read(void)
{
  uint8_t i, data;
  for (i = 0; i < 8; i++)
  {
    while (!(HAL_GPIO_ReadPin(DHT11_GPIO_Port, DHT11_Pin)))
      ;                                                            // 拉高
    delay(40);                                                     // 等待40 us
    if (HAL_GPIO_ReadPin(DHT11_GPIO_Port, DHT11_Pin) == GPIO_PIN_RESET) // 引脚为低电平
    {
      data &= ~(1 << (7 - i)); // 置0
    }
    else
      data |= (1 << (7 - i)); // 引脚为高电平，置1
    while ((HAL_GPIO_ReadPin(DHT11_GPIO_Port, DHT11_Pin)))
      ; // 等待引脚变为低电平
  }
  return data;
}


void DHT11_get()
{
		DHT11_Start();
		Presence = DHT11_Check_Response();
		
		Humi_H=DHT11_Read();//湿度整数部分
		Humi_L=DHT11_Read();//湿度小数部分
		Temp_H=DHT11_Read();//温度整数部分
		Temp_L=DHT11_Read();//温度小数部分
		
		Temperature_integerPart=(float)Temp_H;
		Humidity_integerPart=(float)Humi_H;
			HAL_Delay(2000);

}
